package com.yudean.esb.dao.esb;

import com.yudean.esb.domain.erp.ErpContractVendor;
import com.yudean.esb.domain.erp.ErpControl;
import com.yudean.esb.domain.erp.ErpFwsContract;
import com.yudean.esb.domain.erp.ErpFwsPayments;
import com.yudean.esb.domain.esb.EsbRecvServiceTempData;
import com.yudean.esb.mapper.erp.ErpContractVendorMapper;
import com.yudean.esb.mapper.erp.ErpControlMapper;
import com.yudean.esb.mapper.erp.ErpFwsContractMapper;
import com.yudean.esb.mapper.erp.ErpFwsPaymentsMapper;
import com.yudean.esb.util.SpringUtil;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <pre>
 * 针对于法务系统的DAO
 * </pre>
 *
 * @author Lei Duan<duanlei#gdyd.com>
 * @version 1.0.0
 * @since 0.0.2
 */
@Repository("erpfwsdataDao")
public class FwsDataDao {
    private final static Logger LOGGER = LoggerFactory.getLogger(FwsDataDao.class);

    @Resource
    EsbRecvServiceTempDataDao esbRecvServiceTempDataDao;

    /**
     * 保存控制表的信息
     *
     * @param controlData 控制表信息
     * @return 是否保存成功
     */
    public boolean saveControl(ErpControl controlData) {
        EsbRecvServiceTempData tmpData = controlData.convert2TmpData();
        return esbRecvServiceTempDataDao.insertWithMapKeyInUpperCase(tmpData);
    }

    /**
     * 保存付款信息
     *
     * @param paymentsData 付款的信息
     * @return 是否成功
     */
    public boolean savePayments(ErpFwsPayments paymentsData) {
        EsbRecvServiceTempData tmpData = paymentsData.convert2TmpData();
        return esbRecvServiceTempDataDao.insertWithMapKeyInUpperCase(tmpData);
    }

    /**
     * 保存合同的信息
     *
     * @param contractData 合同的数据
     * @return 成功是否
     */
    public boolean saveContract(ErpFwsContract contractData) {
        EsbRecvServiceTempData tmpData = contractData.convert2TmpData();
        return esbRecvServiceTempDataDao.insertWithMapKeyInUpperCase(tmpData);
    }


    /**
     * 转存ERP的控制表信息
     *
     * @param controlId 控制主键
     */
    public boolean tryTransferControl(String controlId) {
        LOGGER.info("try to transfer control data ={controlId,{}}", controlId);
        LOGGER.info("step 1: query related payments or contract,by controlId");
        List<Map<String, Object>> result = esbRecvServiceTempDataDao.selectFwsPkgById(controlId);
        List<ErpFwsPayments> paymentsList = new ArrayList<ErpFwsPayments>();
        List<ErpFwsContract> contractList = new ArrayList<ErpFwsContract>();
        ErpControl erpControl = null;
        if (result == null || result.size() < 1)
            return true;
        LOGGER.info("find out data size={}", result.size());
        LOGGER.info("step 2: classfy the result data from step1");
        //进行数据分类处理
        for (Map<String, Object> item : result) {
            String dataType = (String) item.get("ID");
            if ("FWS-ERP-CONTRACT".equals(dataType)) {
                LOGGER.info("find out contract data");
                ErpFwsContract contract = ErpFwsContract.mapToThis(item);
                contractList.add(contract);
            } else if ("FWS-ERP-PAYMENT".equals(dataType)) {
                LOGGER.info("find out payment data");
                ErpFwsPayments fwsPayments = ErpFwsPayments.mapToThis(item);
                paymentsList.add(fwsPayments);
            } else if ("FWS-ERP-CONTROL".equals(dataType)) {
                erpControl = ErpControl.mapToThis(item);
            } else {
                LOGGER.error("no of data type found,error!");
                return false;
            }
        }
        return insertToErpTransational(erpControl, contractList, paymentsList);
    }

    /**
     * 控制表信息是否已经存在于数据表中了
     *
     * @param controlId 控制表信息
     * @return TRUE 存在  FALSE 不存在
     */
    public boolean isControlExist(String controlId) {
        return esbRecvServiceTempDataDao.countFwsControlId(controlId) > 0;
    }
    @Resource
    private DataSource dataSource;

    /**
     * 以事务的方式向法务系统插入数据，要求多个表同时成功或者失败
     *
     * @param erpControl   控制表
     * @param contractList 合同信息
     * @param paymentsList 付款信息
     * @return TRUE 成功, FALSE 失败
     */
    private boolean insertToErpTransational(ErpControl erpControl,
                                            List<ErpFwsContract> contractList,
                                            List<ErpFwsPayments> paymentsList) {
        LOGGER.info("now insert data into ERP..........");
        //开始对数据进行事务处理
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        SqlSessionFactory sessionFactory = (SqlSessionFactory) SpringUtil.getBean("sqlSessionFactory");
        SqlSession sqlSession = sessionFactory.openSession(ExecutorType.REUSE, false);
        DataSourceTransactionManager txManager = new DataSourceTransactionManager(dataSource);
        TransactionStatus status = txManager.getTransaction(def);

        try {
            ErpFwsPaymentsMapper erpFwsPaymentsMapper = sqlSession.getMapper(ErpFwsPaymentsMapper.class);
            ErpFwsContractMapper erpFwsContractMapper = sqlSession.getMapper(ErpFwsContractMapper.class);
            ErpControlMapper controlMapper = sqlSession.getMapper(ErpControlMapper.class);
            ErpContractVendorMapper contractVendorMapper = sqlSession.getMapper(ErpContractVendorMapper.class);
            LOGGER.info("stage 2: insert into IDS_AP_CONTRACT_INT && IDS_AP_CONTRACT_VENDOR_INT");
            List<ErpContractVendor> vendorListToInsert = new ArrayList<ErpContractVendor>();
            if (contractList != null && contractList.size() > 0) {
                for (ErpFwsContract contract : contractList) {
                    vendorListToInsert.addAll(contract.getContractVendors());
                }
                contractVendorMapper.insertErpContractVendorList(vendorListToInsert);
                erpFwsContractMapper.insertErpFwsContractList(contractList);
            }
            //付款表
            LOGGER.info("stage 3: insert into IDS_AP_CON_PAYMENTS_INT");
            if (paymentsList != null && paymentsList.size() > 0) {
                erpFwsPaymentsMapper.insertErpFwsPaymentsList(paymentsList);
            }
            //控制表
            LOGGER.info("stage 1: insert into IDS_CONTROL");
            controlMapper.insert(erpControl);
            txManager.commit(status);
            return true;
        } catch (Exception ex) {
            LOGGER.error("err:{},rollback", ex.getMessage(), ex.getCause());
            ex.printStackTrace();
            txManager.rollback(status);
        } finally {
            sqlSession.close();
        }
        return false;
    }
}
